package com.haiyou.dc.es.bi.impl;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.haiyou.common.constant.MsgCode;
import com.haiyou.common.exception.BusinessException;
import com.haiyou.dc.es.bi.EsSearchService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;


/**
 * @author pc
 */
@Service
@Slf4j
public abstract class EsSearchServiceImpl implements EsSearchService {

    @Autowired
    protected Client esClient;
    @Autowired
    protected ObjectMapper objectMapper;

    /**
     * 让子类实现
     *
     * @return
     */
    protected abstract String getIndexName();

    /**
     * 让子类实现
     *
     * @return
     */
    protected abstract String getTypeName();

    @Override
    public Object getById(String id) {
        GetResponse getResponse = this.esClient.prepareGet(getIndexName(), getTypeName(), id).get();
        if (!getResponse.isExists()) {
            throw new BusinessException(MsgCode.NOT_FOUNT, "资源找不到");
        }
        Map<String, Object> object = getResponse.getSource();
        object.put("id", getResponse.getId());
        return object;
    }

    @Override
    public Boolean create(Object object) {
        try {
            IndexResponse indexResponse = this.esClient.prepareIndex(getIndexName(), getTypeName())
                    .setSource(objectMapper.writeValueAsBytes(object), XContentType.JSON).get();
            if (indexResponse.status() == RestStatus.CREATED) {
                return true;
            }
        } catch (JsonProcessingException e) {
            log.error("-------------------->object={},添加失败={}", object, e);
        }
        return false;
    }

    @Override
    public Boolean create(String id, Object object) {
        try {
            IndexResponse indexResponse = this.esClient.prepareIndex(getIndexName(), getTypeName(), id)
                    .setSource(objectMapper.writeValueAsBytes(object), XContentType.JSON).get();
            if (indexResponse.status() == RestStatus.CREATED) {
                return true;
            }
        } catch (JsonProcessingException e) {
            log.error("-------------------->object={},添加失败={}", object, e);
        }
        return false;
    }

    @Override
    public Boolean update(String id, Object object) {
        try {
            // 过滤对象的null属性.
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            UpdateResponse updateResponse = this.esClient.prepareUpdate(getIndexName(), getTypeName(), id)
                    .setDoc(objectMapper.writeValueAsBytes(object), XContentType.JSON).get();
            if (updateResponse.status() == RestStatus.OK) {
                return true;
            }
        } catch (JsonProcessingException e) {
            log.error("-------------------->id={},object={},更新失败={}", id, object, e);
        }
        return false;
    }

    @Override
    public Boolean remove(String id) {
        DeleteResponse deleteResponse = this.esClient.prepareDelete(getIndexName(), getTypeName(), id).get();
        return deleteResponse.status() == RestStatus.OK ? true : false;
    }

    @Override
    public Boolean deleteAndCreate(String id, Object object) {
        if (remove(id)) {
            return create(id, object);
        }
        return false;
    }
}
